package com.raincat.tools.nettools;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkRequest;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.util.ArrayList;

/**
 * <pre>
 *     author : RainCat
 *     org    : Shenzhen JingYu Network Technology Co., Ltd.
 *     e-mail : nining377@gmail.com
 *     time   : 2020/03/23
 *     desc   : 网络状态监控
 *     version: 1.0
 * </pre>
 */
class NetStatusManager {
    private static NetStatusManager netStatusManager;
    private static ArrayList<Request> requestTask = new ArrayList<>();

    /**
     * 单例模式
     *
     * @param context 上下文
     * @return 返回值
     */
    static NetStatusManager getInstance(Context context) {
        if (netStatusManager == null) {
            Application application = (Application) context.getApplicationContext();
            ConnectivityManager connectivityManager = (ConnectivityManager) application.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
                IntentFilter filter = new IntentFilter();
                filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
                application.registerReceiver(netWorkStateReceiver, filter);
            } else if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.P) {
                NetworkRequest.Builder builder = new NetworkRequest.Builder();
                NetworkRequest request = builder.build();
                assert connectivityManager != null;
                connectivityManager.registerNetworkCallback(request, networkCallback);
            } else {
                assert connectivityManager != null;
                connectivityManager.registerDefaultNetworkCallback(networkCallback);
            }
            netStatusManager = new NetStatusManager();
        }
        return netStatusManager;
    }

    /**
     * 新增网络连接失败的请求
     *
     * @param request 请求
     */
    void addRequest(Request request) {
        for (Request r : requestTask) {
            if (r.context.get() != null && r.context.get().equals(request.context.get())
                    && r.url.equals(request.url) && r.param.equals(request.param))
                return;
        }
        requestTask.add(request);
    }

    /**
     * 网络恢复正常后处理拥塞的请求
     */
    private static void handleRequest() {
        for (Request request : requestTask) {
            if (request.context.get() != null) {
                switch (request.requestMode) {
                    case HttpConfig.HTTP:
                        ConnectHttp connectHttp = new ConnectHttp();
                        connectHttp.init(request);
                        break;
                    case HttpConfig.HTTPS:
                        ConnectHttps connectHttps = new ConnectHttps();
                        connectHttps.init(request);
                        break;
                    case UploadConfig.UPLOAD:
                        ConnectUpload connectUpload = new ConnectUpload();
                        connectUpload.init(request);
                        break;
                    case DownloadConfig.DOWNLOAD:
                        ConnectDownload connectDownload = new ConnectDownload();
                        connectDownload.init(request);
                        break;
                }
            }
        }
        requestTask.clear();
    }

    private static BroadcastReceiver netWorkStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connMgr == null)
                return;
            NetworkInfo wifiNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            NetworkInfo dataNetworkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (wifiNetworkInfo == null || dataNetworkInfo == null)
                return;
            if (wifiNetworkInfo.isConnected() || dataNetworkInfo.isConnected()) {
                handleRequest();
            }
        }
    };

    @RequiresApi(api = android.os.Build.VERSION_CODES.LOLLIPOP)
    private static ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(@NonNull Network network) {
            super.onAvailable(network);
            handleRequest();
        }

//        @Override
//        public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
//            super.onCapabilitiesChanged(network, networkCapabilities);
//            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
//                if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
//                } else {
//                }
//            }
//        }
    };
}
